package com.ibeeking.found.uaa.open.service.impl;

import com.ibeeking.found.auth.api.common.dto.LoginOpenUserDTO;
import com.ibeeking.found.auth.api.feign.TenantLoginClient;
import com.ibeeking.found.common.config.secret.RsaConfig;
import com.ibeeking.found.common.enums.LoginRoleEnum;
import com.ibeeking.found.uaa.open.model.OpenUserDetails;
import com.ibeeking.found.uaa.open.service.IOpenUserDetailsService;
import com.ibeeking.nematos.exception.AuthorizationException;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.encryption.EncryptUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ibeeking
 */
@Service
public class OpenUserDetailsServiceImpl implements IOpenUserDetailsService {

    @Resource
    private TenantLoginClient tenantLoginClient;
    @Resource
    private RsaConfig rsaConfig;

    @Override
    public OpenUserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StringUtils.isBlank(username)) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appId不能为空");
        }
        ResponseResult<LoginOpenUserDTO> responseResult = tenantLoginClient.queryLoginUser(username);
        if (null == responseResult || null == responseResult.getData()) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appId未认证，请联系服务商");
        }
        return queryOpenUser(responseResult.getData());
    }

    @Override
    public OpenUserDetails openLogin(String appId, String appSecret) {
        if (StringUtils.isBlank(appId)) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appId不能为空");
        }
        if (StringUtils.isBlank(appSecret)) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appSecret不能为空");
        }
        try {
            appSecret = EncryptUtils.RsaEncrypt.decrypt(appSecret, rsaConfig.getKeyPair().getPrivate());
        } catch (Exception e) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appSecret不正确");
        }
        ResponseResult<LoginOpenUserDTO> responseResult = tenantLoginClient.queryLoginUser(appId);
        if (null == responseResult || null == responseResult.getData()) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "appId未认证，请联系服务商");
        }
        if (!appSecret.equals(responseResult.getData().getAppSecret())) {
            throw new AuthorizationException(HttpStatus.UNAUTHORIZED.value(), "秘钥不正确");
        }
        return queryOpenUser(responseResult.getData());
    }

    /***
     * 封装查询登录用户
     * @param query 参数
     * @return
     */
    private OpenUserDetails queryOpenUser(LoginOpenUserDTO query) {
        OpenUserDetails openUserDetails = new OpenUserDetails();
        openUserDetails.setId(query.getId());
        openUserDetails.setName(query.getName());
        openUserDetails.setTenantId(query.getTenantId());
        openUserDetails.setIndustry(query.getIndustry());
        openUserDetails.setAppId(query.getAppId());
        openUserDetails.setAppSecret(new BCryptPasswordEncoder().encode(query.getAppSecret()));
        openUserDetails.setAccountNonExpired(true);
        openUserDetails.setAccountNonLocked(true);
        openUserDetails.setCredentialsNonExpired(true);
        openUserDetails.setPublishStatus(true);
        List<SimpleGrantedAuthority> roles = new ArrayList<>();
        roles.add(new SimpleGrantedAuthority(LoginRoleEnum.OPEN.name()));
        roles.add(new SimpleGrantedAuthority(LoginRoleEnum.OPEN.name()));
        openUserDetails.setRoles(roles);
        return openUserDetails;
    }
}
